﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Text;
//using Westwind.Utilities;
//using Westwind.Utilities.Properties;

namespace NEventStore.Persistence.Sql
{
    public static class Helper
    {

        public enum DataAccessProviderTypes
        {
            SqlServer,
            SqLite,
            MySql,
            PostgreSql,

#if NETFULL
    OleDb,
    SqlServerCompact
#endif
        }

        public static DataAccessProviderTypes ResolveDataAccess(string providerName)
        {
            providerName = providerName.ToUpperInvariant();

            if (providerName.Contains("MYSQL"))
            {
                return DataAccessProviderTypes.MySql;
            }

            if (providerName.Contains("SQLITE"))
            {
                return DataAccessProviderTypes.SqLite;
            }

            if (providerName.Contains("POSTGRES") || providerName.Contains("NPGSQL"))
            {
                return DataAccessProviderTypes.PostgreSql;
            }
            throw new NotSupportedException($"{providerName} not support");

        }
        public static DbProviderFactory GetDbProviderFactory(DataAccessProviderTypes type)
        {
            if (type == DataAccessProviderTypes.SqlServer)
                //return SqlClientFactory.Instance; // this library has a ref to SqlClient so this works
                return GetDbProviderFactory("System.Data.SqlClient", "System.Data.SqlClient");

            if (type == DataAccessProviderTypes.SqLite)
            {
#if NETFULL
        return GetDbProviderFactory("System.Data.SQLite.SQLiteFactory", "System.Data.SQLite");
#else
                return GetDbProviderFactory("Microsoft.Data.Sqlite.SqliteFactory", "Microsoft.Data.Sqlite");
#endif
            }
            if (type == DataAccessProviderTypes.MySql)
                return GetDbProviderFactory("MySql.Data.MySqlClient.MySqlClientFactory", "MySql.Data");
            if (type == DataAccessProviderTypes.PostgreSql)
                return GetDbProviderFactory("Npgsql.NpgsqlFactory", "Npgsql");
#if NETFULL
    if (type == DataAccessProviderTypes.OleDb)
        return System.Data.OleDb.OleDbFactory.Instance;
    if (type == DataAccessProviderTypes.SqlServerCompact)
        return DbProviderFactories.GetFactory("System.Data.SqlServerCe.4.0");                
#endif

            throw new NotSupportedException(string.Format("UnsupportedProviderFactory" + type.ToString()));
        }

        public static DbProviderFactory GetDbProviderFactory(string dbProviderFactoryTypename, string assemblyName)
        {
            var instance = ReflectionUtils.GetStaticProperty(dbProviderFactoryTypename, "Instance");
            if (instance == null)
            {
                var a = ReflectionUtils.LoadAssembly(assemblyName);
                if (a != null)
                    instance = ReflectionUtils.GetStaticProperty(dbProviderFactoryTypename, "Instance");
            }

            if (instance == null)
                throw new InvalidOperationException(string.Format("UnableToRetrieveDbProviderFactoryForm" + dbProviderFactoryTypename));

            return instance as DbProviderFactory;
        }
    }
}
